/**
 * 3η ΓΕ 2013-2014 - Super Market
 * ΦΡΑΓΚΟΥΛΟΠΟΥΛΟΥ ΕΜΜΑΝΟΥΕΛΑ (69298)
 * ΧΑΛΔΑΣ ΧΑΡΑΛΑΜΠΟΣ (69305)
 * ΧΟΡΜΟΒΙΤΗΣ ΙΩΑΝΝΗΣ (69325)
 * ΧΟΥΣΤΟΥΛΑΚΗ ΕΥΑΓΓΕΛΙΑ (69327)
 */
package simulation;

import java.util.Date;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextArea;
import model.Purchase;

/**
 * Class διαχείρισης ενός Νήματος
 */
public class PurchaseThread extends Thread {
    private final CCAuthority ccAuthority;
    
    
    private xmlRecord record;

    public xmlRecord getRecord() {
        return record;
    }

    
    JTextArea resultsTextArea;
    int threadID;
    
        
    public PurchaseThread(CCAuthority ccAuthority, JTextArea resultsTextArea, int threadID) {
        this.ccAuthority = ccAuthority;
        this.threadID = threadID;
        this.resultsTextArea = resultsTextArea;
        this.record = new xmlRecord();
    }
    
    @Override
    public void run() {
        Random random = new Random();
        
        // Μήνυμα προς το χρήστη
        printMessage("Έναρξη");
        // Δημιουργία Αγοράς
        Purchase purchase = GeneralLib.createPurchase();
        record.setPurchaseId(0);
        record.setResult("NOK");
        record.setPurchaseDate(purchase.getDatetime());
        record.setAmount(purchase.getAmount());
        record.setPoints_earned(purchase.getPointsEarned());
        record.setDelivery(purchase.getDelivery());
        record.setStore(purchase.getStore().getName());
        record.setCustomer(purchase.getCustomer().getLastName() + " " +
                            purchase.getCustomer().getFirstName());
        
        // true όταν η αρχή πιστοποίσησς καρτών
        // εξυπηρετει 0 ή 1 συναλλαγή, διαφορετικά false.
        boolean connected = ccAuthority.connect();
        int retries = 1;    // 1η Προσπαθεια
        String message = "1η προσπάθεια σύνδεσης - " +
                            ((connected)? "Επιτυχής":"Ανεπιτυχής");
        printMessage(message);
        record.getRetriesList().add(new retry(1, new Date (), this.getName()));
        
        
        // Αν δεν υπάρχουν διαθέσιμες συνδέσεις...
        while (!connected) {
            // Έχει ξεπεράσει τις 3 προσπάθειες;
            if (retries == 3) {
                // Αποσύνδεση χωρίς συναλλαγή
                ccAuthority.disconnect();
                printMessage("Απόρριψη Σύνδεσης λόγω φόρτου της υπηρεσίας");
                 break;
            }
            // Τυχαίο πλήθος δευτερολέπτων αναμονής (από 1 έως 10)
            int waitSeconds = 1 + random.nextInt(10);
            printMessage("Αναμονή : " + waitSeconds + " sec");

            // Μετατροπή με ms
            long waitTime = waitSeconds * 1000;
            
            // Αναμονή
            try {
                sleep(waitTime);
            } catch (InterruptedException ex) {
                Logger.getLogger(PurchaseThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            // Προσπάυεια για νέα Σύνδεση
            retries++;
            record.getRetriesList().add(new retry(retries, new Date (), this.getName()));
            connected = ccAuthority.connect();
            message = retries + "η προσπάθεια σύνδεσης - " +
                        ((connected)? "Επιτυχής":"Ανεπιτυχής");
            printMessage(message);

        }
        record.setRetries(retries);
        
        // Όταν φτάσουμε εδώ, ή έχει γίνει η σύνδεση,
        // ή έχουν γίνει 3 αποτυχημένες προσπάθεις.
        if (connected) {
            // Προσπάθεια Έγκριση Συναλλαγής
            Boolean isCardValid = ccAuthority.validateCard (purchase);
            message = "Έγκριση Συναλλαγής: " + 
                      ((isCardValid)? "Επιτυχής":"Ανεπιτυχής");
            printMessage(message);
            
            // Καταχώρηση Αγοράς (μόνο αν εγκρίθηκε η συναλλαγή)
            Boolean saved = false;
            if (isCardValid) {
                saved = GeneralLib.savePurchase (purchase);
                message = "Ολοκλήρωση Συναλλαγής: " + 
                      ((saved)? "Επιτυχής":"Ανεπιτυχής");
                printMessage(message);
                if (saved) {
                    record.setPurchaseId(purchase.getPurchaseId());
                    record.setResult("OK");
                }
            }

            
            // Αποσύνδεση
            ccAuthority.disconnect();
            printMessage("Τερματισμός");
        }
    }
    
    private void printMessage (String message) {
        synchronized (resultsTextArea) {
            message = "Νήμα Νο: " + threadID + " - " +message + "\n";
            resultsTextArea.append(message);
        }
    }
}
